package com.cobra.mall.config;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cobra.mall.domain.goods.entity.GoodsEntity;
import com.cobra.mall.domain.goods.service.inter.GoodsService;
import com.cobra.mall.domain.order.entity.OrderEntity;
import com.cobra.mall.domain.order.service.inter.OrderService;
import com.cobra.mall.util.MallUtil;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

@Component
public class MallConsumer {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private OrderService orderService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private GoodsService goodsService;


    @KafkaListener(topics = MallConst.KAFKA_TOPIC_ORDER_NAME)
    @Transactional
    public void createOrder(String  message) throws Exception {
        OrderEntity orderEntity = MallUtil.fromJson2Obj(message, OrderEntity.class);
        //加一个分布式锁
        RLock lock = redissonClient.getLock(MallConst.GOODS_LOCK_PREFIX+orderEntity.getGoodsId());
        try {
            lock.lock(10, TimeUnit.SECONDS);
            //处理业务逻辑
            //查询库存
            GoodsEntity goodsEntity = goodsService.getById(orderEntity.getGoodsId());
            if(goodsEntity.getStock()<orderEntity.getGoodsNum()){
                throw new RuntimeException("Not enough stock");
            }
            //扣库存
            goodsEntity.setStock(goodsEntity.getStock()-orderEntity.getGoodsNum());
            UpdateWrapper<GoodsEntity> updateWrapper = new UpdateWrapper<GoodsEntity>();
            updateWrapper.eq("id",goodsEntity.getId());
            updateWrapper.set("stock",goodsEntity.getStock());
            goodsService.update(goodsEntity,updateWrapper);
            //录入订单
            orderService.save(orderEntity);
            //完成之后更新缓存信息
            redisTemplate.opsForValue().set(MallConst.GOODS_PREFIX+orderEntity.getGoodsId(),MallUtil.fromObj2Json(goodsEntity),MallUtil.getRandom(200,500),TimeUnit.SECONDS);
        } finally {
            lock.unlock();
        }
    }
}
